package cn.sh.tools.util;

import cn.hutool.core.util.StrUtil;
import com.google.common.collect.Sets;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.ResourceUtils;

import java.io.FileNotFoundException;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors;

/**
 * @Description 系统属性
 * @Classname PropertiesUtils
 * @Date 2023/6/5
 * @Author sh
 **/
@Slf4j
public class SystemPropertiesUtils {

    /**
     * "sun.boot.class.path" —— 启动类加载器（BootstrapClassLoader）
     * "java.ext.dirs" —— 扩展类加载器（ExtClassLoader）
     * "java.class.path" —— 应用程序类加载器（AppClassLoader）
     */
    private static final Set<String> CLASS_LOADER_SET = Sets.newHashSet(
            "sun.boot.class.path", "java.ext.dirs", "java.class.path");
    private static final char PROP_SEPARATOR = ';';
    private static final Map<String, Set<String>> classLoaderValueSetConMap = new ConcurrentHashMap<>();

    static {
        CLASS_LOADER_SET.forEach(classLoaderKey -> {
            String originPropValue = System.getProperty(classLoaderKey);
            if (StrUtil.isNotBlank(originPropValue)) {
                Set<String> propValueSet = new HashSet<>(StrUtil.split(originPropValue, PROP_SEPARATOR));
                propValueSet = propValueSet.stream().sorted().collect(Collectors.toCollection(LinkedHashSet::new));
                classLoaderValueSetConMap.put(classLoaderKey, propValueSet);
            }
        });

        try {
            // "classpath:"字符串指的是类路径起点。当要求获取【类路径的根目录】时，则使用"classpath:"。
            String classpath = ResourceUtils.getURL("classpath:").getPath();
            classLoaderValueSetConMap.put(ResourceUtils.CLASSPATH_URL_PREFIX, Sets.newHashSet(classpath));
        } catch (FileNotFoundException e) {
            log.error("get classpath error", e);
        }
    }

    public static Map<String, Set<String>> listValueOfClassLoader() {
        return classLoaderValueSetConMap;
    }

    public static Set<String> getClassLoaderValue(String inClassLoaderKey) {
        return classLoaderValueSetConMap.computeIfAbsent(inClassLoaderKey,
                classLoaderKey -> {
                    String originPropValue = System.getProperty(classLoaderKey);
                    Set<String> propValueSet = new HashSet<>();
                    if (StrUtil.isNotBlank(originPropValue)) {
                        propValueSet.addAll(StrUtil.split(originPropValue, PROP_SEPARATOR));
                    }
                    return propValueSet;
                });
    }

}
